home *** CD-ROM | disk | FTP | other *** search
- dUFLP/dHUNG
- Coding Standards and Conventions
- Version 0.8
- July 23, 1993
-
-
- dUFLP -- dBASE Users Function Library Project -- Coding Standards and
- Conventions -- Based upon the HUNGARIAN / xBase Conventions by Robert A.
- DiFalco. These Standards and Conventions have been defined and generally
- agreed upon by several of the 'regulars' on the Borland (once Ashton-
- Tate) Bulletin Board System (BORBBS (now defunct)), but are by no means
- a rigid definition.
-
- This file contains modifications to Robert DiFalco's (CIS: 71610,1705)
- HUNG standard for X-Base languages; it was developed by members of the
- Ashton-Tate/Borland Bulletin Board System to be used in a user-developed
- library. Several aspects of this document have been changed, as the
- dUFLP standards are more aimed at dBase than other programming
- languages, but have been only slightly modified where needed, and some
- duplicate definitions were removed in the variable naming practices. The
- original document (HUNG14.ZIP) may be found on the CompuServe dBASE
- Forum.
-
- The purpose of this document is to define some coding standards to be
- used in the library for dUFLP, Please attempt to follow these standards
- as closely as possible when creating Functions and Procedures to be
- included in this library. Thank you ... (most of the text from this
- point on is DiFalco's own words)
- ------------------------------------------------------------------------
- Let me start off by stating that these are only my opinions on naming
- conventions for xBase programming. In my opinion these methods are
- extensible to C, ASM, BASIC and just about any other programming
- language. It looks very similar to Hungarian notation as outlined by
- Charles Simonyi of Microsoft Corporation. Don't be fooled, however, this
- is much different. I find it more intuitive and logical though that may
- pertain only to my thinking.
-
- These conventions take in the same factors as outlined by Charles
- Simonyi for creating names in a program. The factors listed below are
- directly quoted from his monograph.
-
- Begin quote:
- 1. Mnemonic value - so that the programmer can remember the name.
-
- 2. Suggestive value - so that others can read the code easily.
-
- 3. "Consistency" - this is often viewed as an aesthetic idea, yet it
- also has to do with the information efficiency of
- the program text. Roughly speaking, we want
- similar names for similar quantities.
-
- 4. Speed of decision- we cannot spend too much time pondering the name
- of a single quantity, nor is there time for typing
- and editing extremely long variable names.
- End quote:
-
- In dBase, our variable names have even a more pressing reason for short
- identifiers since we only have 10 characters to work with. To alleviate
- using needless characters, we will use lowerUpper combinations instead
- of dividing underscores.
-
- =====================================
- Procedure/Function Naming conventions
- =====================================
- Procedures and Functions will be heretofore called "Functions". Function
- names will not be "typed" as variables. As dBase in general heads
- towards object oriented approaches it is important to allow our
- Functions to return multiple types. This negates the approach of typing
- Functions by return variable type. Instead we will apply a "loose" set
- of rules to Functions. Native language functions will be in all
- lowercase while 3rd party or "home grown" functions (UDF or User-
- Defined Functions) will be mixed case beginning with a single Capital
- letter.
-
- -------------
- UDF Name Case
- -------------
- All User Defined Functions will be mixed case, with no underscores. The
- first letter will be upper case, e.g. AllTrim.
-
- 1. Functions will start with a capital letter followed by lower case
- letters thus distinguishing them from variables. If the Function name
- can be better expressed by two or three identifiers an UpperLower
- combination will be used rather than underscores to delimit
- identifiers. Consider the following Examples:
-
- ClrSet() - Sets colors
- SaveGets() - Saves active get list
- PrnScr() - Prints the screen
- GetPass() - Gets a password
- Choose() - Menu of items to "choose" from
-
- 2. Conversion Functions will start with the value they take and end with
- converted value separated by the number 2. Some examples would be as
- follows:
-
- Str2Arr() - Changes a string to an array.
- Hex2Dec() - Changes a Hex string into a decimal numeric.
- Clr2Attr() - Changes a color string to an integer attribute.
- Dbf2Arr() - Loads a DBF into an array.
-
- 3. Where possible, use standard qualifiers as outlined in the section
- dedicated to "Variable Naming Conventions". A few examples follow.
-
- cFName = HCUST->FNAME
- cLName = HCUST->LNAME
- cAddr = HCUST->ADDR
- nAge = HCUST->AGE
- lActive = HCUST->ACTIVE
- nBalance = HLOAN->BALANCE
- ( Please note that the storage operators ( "=" ) are lined up for
- easy reading giving a table appearance. )
-
- 4. Where possible, express the function or procedure in less than three
- qualifiers ( names ). Refer to the examples given for Rule 1.
-
- 5. The keywords PROCEDURE, FUNCTION and RETURN shall be in all
- uppercase.
-
- FUNCTION SayStr
-
- parameters cMsg
-
- m->xSavClr = set( "ATTRIBUTES" )
- set color to rg+/r
-
- ? m->cMsg
-
- set color to &xSavClr.
-
- RETURN ""
-
- dBASE native functions shall be typed in all lowercase to delineate them
- from non-native functions as in the above call to set().
-
-
- ------------------
- Reserved Word Case
- ------------------
- Except for the reserved words 'FUNCTION', 'PROCEDURE', and 'RETURN', all
- dBASE reserved words should be lower case.
-
- -----------------------------
- File Name and Field Name Case
- -----------------------------
- All reference to DOS files (e.g. .dbf, .fmt, .frg, etc.) and field
- names are to be in upper case. Underscores are allowed.
-
- ------------
- Case Summary
- ------------
- all lower : built-in commands and functions
- mIxed, fIrst lEtTer lOWer : memvars
- MiXed, First LetTer UpPer : UDFs
- ALL UPPER : files and fields, and the commands
- FUNCTION, PROCEDURE, and RETURN
-
- =============================================
- DBF and Field related Punctuation Conventions
- =============================================
- There are some rules noteworthy for DBF, NDX/MDX, ALIAS and FIELD
- operations to delineate them from Functions and Variables. FIELD names
- will NOT be typed by a lowercase type identifier as with Variables.
-
- 1. Database and Index files, as well as Field names will always be
- expressed in capital letters. As dBase's main point of existence is
- the manipulation of DataFiles, this will make them stand out against
- variables and other qualifiers.
- 2. Where possible they will use the same standard qualifiers used for
- Variables and Functions. See the examples for Rule 3 of
- "Procedure/Function Naming Conventions".
-
- 3. Fields will be referenced by an ALIAS. Consider the following.
-
- HACCT->ACCNUM
- HCONST->PASSWORD
- HCONST->COMPANY
-
- 4. Variables referencing Fields will have the same name as the Field
- with the addition of the dHUNG type prefix.
-
- cFName = HCUST->FNAME
- cLName = HCUST->LNAME
- cAddr = HCUST->ADDR
- nAge = HCUST->AGE
- lActive = HCUST->ACTIVE
- nBalance = HLOAN->BALANCE
-
- ( Please note that the storage operators ( "=" ) are lined up for
- easy reading giving a table appearance. )
-
- Variables should use the prefix: 'M->' to indicate to dBASE that
- they are memory variables. This will speed the internal processing
- of any routine, as dBASE always checks the list of fieldnames before
- making changes to, or referring to memory variables. By using the
- prefix 'M->', dBASE knows it is a memory variable, and bypasses
- the list of fieldnames.
-
- 5. With regard to DBF file names, data, index or otherwise they should
- all begin with a common prefix and that prefix is similar to the
- name.
-
- This insures that I have few naming conflicts with other systems
- that may reside on the computer and just about guarantees I can
- separate my files out if they get placed into a common subdirectory.
-
- 6. Index filenames should reflect the file that they belong to but
- should not attempt to indicate what the index expression is. A
- much cleaner routine results when index files are simply numbered.
-
- HACCTS.DBF ---> HACCTS1.NDX
- HACCTS2.NDX
- HACCTS3.NDX
-
- Internally the only information I am required to keep is the index
- key in an array and all indexes can be rebuilt in the order of their
- respective suffix number.
-
- ===============================
- Command Punctuation Conventions
- ===============================
- This area of my dHUNG naming conventions will probably meet with the
- most opposition. User Defined Commands will use descriptive names as
- outlined in "Procedure/Function Naming Conventions". User Defined or
- not, Commands will have one Rule.
-
- 1. All Commands will be typed with lower case letters.
-
- The reasons for this are simple. This will delineate commands from
- variables, functions and DBF elements. Consider the following examples.
-
- FUNCTION CmdExample
-
- use HCUST
- set index to HCUST1, HCUST2, HCUST3
-
- cLName = "DiFalco"
-
- seek m->cLName
-
- HCUST->AGE = 28
- HCUST->ACTIVE = .t.
- HCUST->LNAME = m->cLName
-
- close database
-
- RETURN ""
-
- ( Please take note that in replace statements we also line up the "with"
- portion of the command as we do storage operators. )
-
- ===========================
- Variable Naming Conventions
- ===========================
- This is the heart of a well designed system. Variable names must give
- the most amount of information possible in its name while using the
- minimum number of characters possible.
-
- All memory variables (memvars) are mixed case names, consisting of 1-10
- alphanumeric characters. The first character is always a lower case
- type prefix. Underscores are only used as scope prefixes. Memvar names
- should not repeat type prefix information.
-
- But memvars may have a combination of tags that will in most cases
- appear in this order.
-
- 1. A single lower case variable defining its type as returned by a
- Type() function called a "Type Prefix".
- 2. An Optional state called a "State Qualifier"
- 3. A "Standard Qualifier Tag".
- 4. An Optional "Pointer Reference".
-
- -------------
- Type Prefixes
- -------------
- A type prefix is the first character of a variable that represents the
- type the programmer intends for the variable. Below is the list of
- dBASE-specific type prefixes together with examples:
-
- Prefix Type Example
- ------ ---- -------
- a Array aList
- c Character cFName
- d Date dPmtDue
- f Float fAngle
- l Logical lExitMenu
- m Menu mMain
- n Numeric nHours
- p Pad pOpenDbf
- s Screen sBackgrnd
- u popUp uFlds
- w Window wError
- x undefined xLookUp
-
- For temporary variables of distinct type or pointers this single prefix
- can be used by itself. Consider this example.
-
- m->n = 0
- do while m->n < m->nFldMax
- m->n = m->n + 1
- aFldName[n] = Field( m->n )
- enddo
-
- --------------
- Scope Prefixes
- --------------
- In dBASE, a variable can be either local to a procedure or global to all
- procedures. This distinction is represented by the scope prefix.
- Variables that are global are represented by an underscore after the
- type prefix; variables that are local to a procedure have a null scope
- prefix. For example, c_DbfFile is a character variable that is global;
- cDbfFile would be the same variable if it was local.
-
- -------------------------
- Sample "State Qualifiers"
- -------------------------
- New - a New state
- Sav - a Saved state
- Tem - a Temporary state
-
- --------------------------------
- Sample "Standard Qualifier" tags
- --------------------------------
- Attr - Attribute
- Clr - Color
- Crs - Cursor
- Dbf - of or pertaining to a DBF
- F - First as in cFName
- File - Any type of file
- Fld - Field
- L - Last as in cLName
- Msg - Message
- Name - a name
- Ndx - of or pertaining to an Index ( or Mdx )
- Rec - Record Number
- Ret - Return value ( lRet = .f. )
- Str - String
- T - Top
- L - Left
- B - Bottom
- R - Right
- Row - Row
- Col - Column
- X - Row
- Y - Column
-
- Please note that Standard Qualifiers can be used in combinations as in
- the following examples.
-
- nTRow - Top Row
- cFName - First name
- cDbfFile - a Database file
- cNdxFile - an Index File
-
- ---------------------------
- Sample "Pointer References"
- ---------------------------
- 1,2,3 - State pointer references as in cSavClr1, cSavClr2, etc.
- Max - Strict upper limit as in nFldMax, maximum number of Fields
- Min - Strict lower limit as in nRecMin, minimum number of Records
-
-
- These lists are to serve as samples and building blocks. They can and
- should be added to. Lets look at a few examples of the conventions at
- work. This should dispel the myth that notation conventions cannot be
- applied to variables with a 10 character maximum length.
-
- ==========================================
- Poorly Designed and Well Designed Examples
- ==========================================
-
- WRONG RIGHT WHY
- ------------------------------------------------------------------------
- nFldNum nFld Number is indicated by the Type Prefix making
- the word Num redundant and a needless use of
- character space.
- Count n n serves as a temporary count index. Count has
- no Type Prefix - could also be called nCount.
- Last_Name cLName This is one of the most horrendous mistakes.
- First we do not specify the variable type.
- Second we needlessly spell out LAST and worst of
- all we use up a precious character by using an
- underscore instead of using the UpperLower
- combination.
- SaveScreenA sSav1 No Type Prefix, needless use of characters. The
- SaveScreenB sSav2 alphabetical reference is allowable though I
- SaveScreenC sSav3 prefer to use a numeric reference. Use of 's'
- type prefix removes need to use Scrn or sScreen.
- ColorStr xClr No Type Prefix. Needless use of characters. This
- shows the usage of 'unknown' type with the Type
- Prefix 'x' (colors are character strings in
- specific formats, but do not require a special
- type).
- nRecNo nRec The use of "No" is redundant.
- PrintReset xPrnReset Also could have been shortened to cPrnRst.
- MessageStr cMsg These are starting to become obvious, don't you
- think?
-
- ======================
- Standard Header Format
- ======================
- Below is the recommended header format to be used for procedures/
- functions. This will allow the automated maintenance of library
- functions as well as documenting the routine. By using this header, it
- will make it possible to create a routine either in dBASE or some other
- software that can generate a library listing, giving the pertinent
- information. Please also note EoF/EoP comment at the END of the
- function or procedure. In order to speed up processing, we are using
- the prefix "M->" to specify memory variables in the code. Finally, note
- that we are keeping text in particular, although it is useful to keep
- the code in the same limit, to a right margin of 72 characters.
-
- FUNCTION AllTrim && {ver 0.8}
- *-----------------------------------------------------------------------
- *-- Programmer..: HazMatZak
- *-- Date........: 07/02/1991
- *-- Notes.......: Used to remove leading and trailing blanks from
- *-- a string.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 05/23/1991 0.1 - Original version (CLW)
- *-- 06/18/1991 0.2 - Revision to modify for dHUNG
- *-- 06/19/1991 0.3 - Revised for ...
- *-- 06/24/1991 0.4 - Revised for ...
- *-- 06/25/1991 0.5 - Revised again by Ken Mayer
- *-- to give smaller header ...
- *-- etc.
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: AllTrim(<cArg>)
- *-- Example.....: ? AllTrim(" Test string ")
- *-- Returns.....: String to be trimmed (i.e.:"Test string")
- *-- Parameters..: cArg = String to be trimmed
- *-----------------------------------------------------------------------
-
- parameters cArg
-
- RETURN ltrim(rtrim(m->cArg))
- *-- EoF: AllTrim()
-
- -------------
- Documentation
- -------------
- It is always a good idea to document code -- never assume you will be
- the only programmer to read your code. If it is being posted on
- CompuServe, a lot of people may download it. If they wish to understand
- what you are doing, or use just portions of your code, it is very useful
- to explain in at least some detail what your program/function/procedure
- is doing. We are not going to suggest more than attempt to make the
- documentation neat, concise, and to the point (don't ramble).
-
- -----------
- dUFLP NOTES
- -----------
- Thinking of contributing to the dBASE Users' Function Library Project?
- If so, please consider the following:
-
- 1) Margins 72 characteres wide (both documentation _and_ code).
- 2) Use of "m->" prefix.
- 3) Use of the dot at the end of macro substitution calls (¯o.).
- 4) Use spaces, rather than tabs, and please try to indent the code to
- three spaces (for each indent), rather than 8, which is the dBASE
- default tab.
- 5) Please use the header as shown above for all code (exactly as it
- is above, down to the number of dots in the header lines).
- 6) Please use the "private" statement for all memvars used within your
- function or procedure.
-
- Also, please read the file: CONTRIB.TXT.
-
- ----------------------
- dHUNG Revision History
- ----------------------
- 1991-05-23 0.1 Initial revision (clw)
- 1991-06-18 0.2 Revision after notations vote (clw)
- 1991-06-19 0.3 Memvars, Files, Fields, UDFs, Case Summary (HazMatZak)
- 1991-08-20 0.4 Added official header example (clw)
- 1991-08-26 0.5 Combined original DiFalco document (HUNG14.ZIP) with
- CLW's dHUNG documentation, and the header information
- (KenMayer).
- 1991-08-30 0.6 Minor corrections to make this dBASE specific
- (KenMayer).
- 1992-04-16 0.7 Minor corrections to make this 'Politically Correct'.
- (Ken Mayer (KenMayer))
- 1993-07-23 0.8 Changed text to fit 72 character right margin, and
- added 'M->' to sample code.